package com.kim.oauth.common.util;

import com.kim.oauth.common.constants.CustomTokenInfoConstants;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Map;

/**
 * 用户认证信息获取工具类
 */
@Component
public class UserUtils {

    /**
     * redis
     */
    private final RedisTemplate<String, Object> redisTemplate;

    public UserUtils(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * token key
     */
    private static final String TOKEN = "token:";

    /**
     * jwt方式{@value}
     */
    private final static String JWT_TOKEN_STORE = "jwt";

    /**
     * redis方式{@value}
     */
    private final static String REDIS_TOKEN_STORE = "redis";

    /**
     * redis-custom方式{@value}
     */
    private final static String REDIS_CUSTOM_TOKEN_STORE = "redis-custom";

    /**
     * token存储类型
     */
    @Value("${surge.oauth2.token-store.type}")
    private String type;

    /**
     * 获取token中所有用户信息
     */
    private Map hasToken() {
        Object principal;
        // jwt || redis
        if (JWT_TOKEN_STORE.equals(type)) {
            SecurityContext securityContext = SecurityContextHolder.getContext();
            principal = securityContext.getAuthentication().getPrincipal();
        } else if (REDIS_CUSTOM_TOKEN_STORE.equals(type)) {
            SecurityContext securityContext = SecurityContextHolder.getContext();
            OAuth2AuthenticationDetails oAuth2AuthenticationDetails = (OAuth2AuthenticationDetails) securityContext.getAuthentication().getDetails();
            principal = redisTemplate.opsForValue().get(TOKEN + oAuth2AuthenticationDetails.getTokenValue());
        } else if (REDIS_TOKEN_STORE.equals(type)) {
            SecurityContext securityContext = SecurityContextHolder.getContext();
            principal = CustomTokenInfoUtil.getAuthenticationUserInfo(securityContext.getAuthentication());
        } else {
            principal = null;
        }
        if (principal instanceof Map) {
            return (Map) principal;
        }
        return null;
    }

    /**
     * 获取当前token的用户名
     */
    public String getCurrentAuthenticationUsername() {
        Map map = hasToken();
        if (map != null && null != map.get(CustomTokenInfoConstants.USERNAME)) {
            return String.valueOf(map.get(CustomTokenInfoConstants.USERNAME));
        }
        return null;
    }

    /**
     * 获取当前token的手机号
     */
    public String getCurrentAuthenticationPhone() {
        Map map = hasToken();
        if (map != null && null != map.get(CustomTokenInfoConstants.PHONE)) {
            return String.valueOf(map.get(CustomTokenInfoConstants.PHONE));
        }
        return null;
    }

    /**
     * 获取当前token的用户id
     */
    public String getCurrentAuthenticationUserId() {
        Map map = hasToken();
        if (map != null && null != map.get(CustomTokenInfoConstants.USER_ID)) {
            return String.valueOf(map.get(CustomTokenInfoConstants.USER_ID));
        }
        return null;
    }

    /**
     * 获取权限
     */
    public Collection<String> getCurrentAuthorities() {
        Map map = hasToken();
        if (map != null) {
            return (Collection<String>) map.get(CustomTokenInfoConstants.AUTHORITIES);
        }
        return null;
    }

    /**
     * 获取简易用户角色权限
     */
    public Collection<String> getCurrentSimpleAuthorities() {
        Map map = hasToken();
        if (map != null) {
            return (Collection<String>) map.get(CustomTokenInfoConstants.SIMPLE_AUTHORITIES);
        }
        return null;
    }

    /**
     * 获取设置密码状态
     */
    public Boolean getCurrentAuthenticationPwdSet() {
        Map map = hasToken();
        if (map != null) {
            return (Boolean) map.get(CustomTokenInfoConstants.PASSWORD);
        }
        return null;
    }


}
